#ifndef DRIVERJACK_H
#define DRIVERJACK_H
//
#include <jack/jack.h>
//#include "datatypes.h"
#include <QStringList>
// 32 audio in and outs, 32 midi in and outs

//
class QString;
class EngineHandler;
class QWaitCondition;

namespace DJ {
    typedef int ReturnCode;
    typedef float Sample;
    const char AUDIO_OUT_PORT_PREFIX[] = "aOut%1";
    const char AUDIO_IN_PORT_PREFIX[] =  "aIn%1";
    const char MIDI_OUT_PORT_PREFIX[] =  "mOut%1";
    const char MIDI_IN_PORT_PREFIX[] =  "mIn%1";
    const char NAME_OF_DRIVER_JACK[] = "QKEYMETRO";
    const int MAX_N_PORTS = 32;
    const int N_DIGITS_IN_A_PORT_NAME = 2;
};

class DriverJack
{
public:
    QStringList * getPhysicalPortNames(bool isJackOutput, bool isAudio);
    QStringList * getMyPortNames();

    QString setPortName(int portID, const QString & portName);

    int	registerPort(DJ::Sample ** buffer, bool isOutput, QString name = QString(""));

    DJ::ReturnCode deletePort(int portID);
    DJ::ReturnCode connectDefaultPorts();

    const QStringList & getConnections(const QString & myPortName);
    DJ::ReturnCode connectPort(const int myPortID, const QString & extPortName);
    DJ::ReturnCode disconnectPort(const QString & myPortName,
                                  const QString & extPortName);
    QWaitCondition & getWaitCondition();

    const QString & getNameOfDriver();

    int getBufferSize();
    int getSampleRate();

    DJ::ReturnCode init(void (*setBufferSize)(int), void (*setSampleRate)(int)); // set all prerequisites
    DJ::ReturnCode stop(); // stop process audio
    DJ::ReturnCode start();// start process audio

    DriverJack(const char * nameOfClient = DJ::NAME_OF_DRIVER_JACK);
    ~DriverJack();
private:
    enum DriverState {CREATED, INITED, STARTED, STOPED} driverState_;
    QString nameOfClient_;
    const QString nameOfDriver_;

    struct StaticData;
    struct AudioPortStruct;

    static StaticData staticData_;
};
#endif
